import { createVNode, render, VNode } from 'vue'
import RamblerDialog from '@/components/RamblerDialog.vue'

interface DialogConfig {
  title?: string
  content?: string | VNode
  okText?: string
  cancelText?: string
  onOk?: () => void
  onCancel?: () => void
  width?: string | number
  closable?: boolean
  maskClosable?: boolean
  draggable?: boolean
  centered?: boolean
  zIndex?: number
}

interface ConfirmDialogConfig extends DialogConfig {
  type?: 'confirm' | 'alert' | 'prompt'
}

class Dialog {
  private static zIndex = 1000

  static confirm(config: ConfirmDialogConfig) {
    return this.openDialog({ ...config, type: 'confirm' })
  }

  static alert(config: ConfirmDialogConfig) {
    return this.openDialog({ ...config, type: 'alert', showCancel: false })
  }

  static prompt(config: ConfirmDialogConfig) {
    return this.openDialog({ ...config, type: 'prompt' })
  }

  private static openDialog(config: ConfirmDialogConfig) {
    const {
      title = '',
      content = '',
      okText = '确定',
      cancelText = '取消',
      onOk = () => {},
      onCancel = () => {},
      width = 416,
      closable = true,
      maskClosable = true,
      draggable = false,
      centered = true,
      zIndex = ++this.zIndex,
      type = 'confirm'
    } = config

    const container = document.createElement('div')
    document.body.appendChild(container)

    const handleClose = () => {
      render(null, container)
      document.body.removeChild(container)
    }

    const handleOk = () => {
      onOk()
      handleClose()
    }

    const handleCancel = () => {
      onCancel()
      handleClose()
    }

    const vnode = createVNode(
      RamblerDialog,
      {
        visible: true,
        title,
        width,
        closable,
        maskClosable,
        draggable,
        centered,
        zIndex,
        okText,
        cancelText,
        showCancel: type !== 'alert',
        'onUpdate:visible': handleClose,
        onOk: handleOk,
        onCancel: handleCancel,
        onClose: handleClose
      },
      {
        default: () => content
      }
    )

    render(vnode, container)
    return vnode.component
  }
}

export default Dialog
